using DBUtil.MetaData;
using DBUtil.Provider.SqlServer.MetaData;
using DotNetCommon.Data;
using DotNetCommon.Extensions;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Index = DBUtil.MetaData.Index;

namespace DBUtil.Provider.SqlServer
{
    /// <summary>
    /// SqlServer数据库管理对象
    /// </summary>
    public partial class SqlServerManage : DBManage
    {
        /// <summary>
        /// 根据DBAccess创建DBManage
        /// </summary>
        /// <param name="db"></param>
        public SqlServerManage(DBAccess db) : base(db) { }

        #region 修改元数据        
        /// <summary>
        /// 重命名表名
        /// </summary>
        /// <param name="oldName">旧表名</param>
        /// <param name="newName">新表名</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <remarks>exec sp_rename 'dbo.table1','table2';</remarks>
        /// <returns></returns>
        public override Result RenameTable(string oldName, string newName, string schemaName = null)
        {
            oldName = db.DealSqlInject(oldName);
            newName = db.DealSqlInject(newName);
            schemaName = db.DealSqlInject(schemaName);
            return Result.Wrap(() =>
            {
                var objName = db.ParseObjectName(oldName, schemaName);
                var newObjName = db.ParseObjectName(newName, schemaName);
                //重命名语句不会改变所属模式,所以: sp_rename 'dbo.test','tt' 而不是: sp_rename 'dbo.test','dbo.tt',也不是 sp_rename 'dbo.test','[tt]'
                string sql = $"exec sp_rename '{objName.NormalName}','{newObjName.Name}'";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 重命名列名
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="oldName">旧列名</param>
        /// <param name="newName">新列名</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <remarks>exec sp_rename 'dbo.table1.name','name2','COLUMN';</remarks>
        /// <returns></returns>
        public override Result RenameColumn(string tableName, string oldName, string newName, string schemaName = null)
        {
            tableName = db.DealSqlInject(tableName);
            oldName = db.DealSqlInject(oldName);
            newName = db.DealSqlInject(newName);
            schemaName = db.DealSqlInject(schemaName);
            return Result.Wrap(() =>
            {
                //把列表当成表名解析
                var objName = db.ParseObjectName(oldName, tableName, schemaName);
                var newObjName = db.ParseObjectName(newName);
                //exec sp_rename 'dbo.table1.name','name2','COLUMN';
                string sql = $"EXEC sp_rename '{objName.FullName}','{newObjName.Name}','COLUMN';";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 修改表说明
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateTableDescription(string tableName, string desc, string schemaName = null)
        {
            tableName = db.DealSqlInject(tableName);
            desc = db.DealSqlInject(desc);
            schemaName = db.DealSqlInject(schemaName);
            var objName = db.ParseObjectName(tableName);
            return updateExtendedProperty(objName.SchemaName, "table", objName.Name, null, null, "MS_Description", desc);
        }

        /// <summary>
        /// 修改视图说明
        /// </summary>
        /// <param name="viewName">视图名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateViewDescription(string viewName, string desc, string schemaName = null)
        {
            viewName = db.DealSqlInject(viewName);
            desc = db.DealSqlInject(desc);
            schemaName = db.DealSqlInject(schemaName);
            var objName = db.ParseObjectName(viewName);
            return updateExtendedProperty(objName.SchemaName, "view", objName.Name, null, null, "MS_Description", desc);
        }

        /// <summary>
        /// 修改函数说明
        /// </summary>
        /// <param name="funcName">函数名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public Result UpdateFuncDescription(string funcName, string desc, string schemaName = null)
        {
            funcName = db.DealSqlInject(funcName);
            desc = db.DealSqlInject(desc);
            schemaName = db.DealSqlInject(schemaName);
            var objName = db.ParseObjectName(funcName);
            return updateExtendedProperty(objName.SchemaName, "FUNCTION", objName.Name, null, null, "MS_Description", desc);
        }

        /// <summary>
        /// 修改存储过程说明
        /// </summary>
        /// <param name="procName">存储过程名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public Result UpdateProcDescription(string procName, string desc, string schemaName = null)
        {
            procName = db.DealSqlInject(procName);
            desc = db.DealSqlInject(desc);
            schemaName = db.DealSqlInject(schemaName);
            var objName = db.ParseObjectName(procName);
            return updateExtendedProperty(objName.SchemaName, "PROCEDURE", objName.Name, null, null, "MS_Description", desc);
        }

        /// <summary>
        /// 修改列说明
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateColumnDescription(string tableName, string colName, string desc, string schemaName = null)
        {
            tableName = db.DealSqlInject(tableName);
            colName = db.DealSqlInject(colName);
            desc = db.DealSqlInject(desc);
            schemaName = db.DealSqlInject(schemaName);
            var objName = db.ParseObjectName(tableName);
            return updateExtendedProperty(objName.SchemaName, "table", objName.Name, "column", db.ParseObjectName(colName).Name, "MS_Description", desc);
        }

        /// <summary>
        /// 修改列说明
        /// </summary>
        /// <param name="viewName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="desc">说明信息</param>
        /// <param name="schemaName">指定schema名称</param>
        public Result UpdateViewColumnDescription(string viewName, string colName, string desc, string schemaName = null)
        {
            viewName = db.DealSqlInject(viewName);
            colName = db.DealSqlInject(colName);
            desc = db.DealSqlInject(desc);
            schemaName = db.DealSqlInject(schemaName);
            var objName = db.ParseObjectName(viewName);
            return updateExtendedProperty(objName.SchemaName, "view", objName.Name, "column", db.ParseObjectName(colName).Name, "MS_Description", desc);
        }

        private Result updateExtendedProperty(string schemaName, string level1type, string level1name, string level2type, string level2name, string propName, string propValue)
        {
            return Result.Wrap(() =>
            {
                level2type = (level2type == null ? "null" : "'" + level2type + "'");
                level2name = (level2name == null ? "null" : "'" + level2name + "'");
                string sql = $"SELECT count(1) FROM fn_listextendedproperty ('{propName}', 'schema', '{schemaName}', '{level1type}', '{level1name}',{level2type},{level2name});";
                string sql2 = "";
                if (db.SelectScalar<string>(sql) == "1")
                {
                    sql2 = $"EXEC sp_dropextendedproperty @name=N'{propName}', @level0type=N'SCHEMA',@level0name='{schemaName}', @level1type=N'{level1type}',@level1name=N'{level1name}', @level2type={level2type},@level2name={level2name};\r\n";
                }
                sql2 += $"EXEC sys.sp_addextendedproperty @name = N'{propName}', @value = N'{propValue}' , @level0type = N'SCHEMA',@level0name = '{schemaName}', @level1type = N'{level1type}',@level1name = N'{level1name}', @level2type = {level2type},@level2name = {level2name};";

                db.ExecuteSql(sql2);
            });
        }

        /// <summary>
        /// 删除指定表,如果存在
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropTableIfExist(string tableName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                var objName = db.ParseObjectName(tableName, schemaName);
                string sql = $"IF (OBJECT_ID('{objName.NormalName}') is not null) DROP table {objName.NormalNameQuoted}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 修改列是否自增
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="identity">自增信息,为空,则表示不自增</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateColumnIdentity(string tableName, string colName, string identity, string schemaName = null)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 修改列是否可为空
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="isNullAble">是否可为空</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateColumnNullAble(string tableName, string colName, bool isNullAble, string schemaName = null)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 修改列是否唯一
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="isUnique">是否唯一</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateColumnUnique(string tableName, string colName, bool isUnique, string schemaName = null)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 修改列类型
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="colName">列名</param>
        /// <param name="type">列类型</param>
        /// <param name="schemaName">指定schema名称</param>
        public override Result UpdateColumnType(string tableName, string colName, string type, string schemaName = null)
        {
            return AlterColumnType(tableName, colName, type, schemaName);
        }

        /// <summary>
        /// 删除指定表的指定列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">要删除的列名</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropColumn(string tableName, string columnName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                var objName = db.ParseObjectName(tableName, schemaName);
                string sql = $"ALTER TABLE {objName.NormalNameQuoted} DROP COLUMN {db.ParseObjectName(columnName).NameQuoted}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 改变指定表的指定列类型
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="columnType">列类型</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public Result AlterColumnType(string tableName, string columnName, string columnType, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                var objName = db.ParseObjectName(tableName, schemaName);
                string sql = $"alter table {objName.NormalNameQuoted} alter column {db.ParseObjectName(columnName).NameQuoted} {columnType}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 修改指定表的指定列是否可以为空
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="canNull">是否可空</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <param name="columnType">列类型,如果columnType为空,程序会自动探索列类型</param>
        /// <returns></returns>
        public Result AlterColumnNullAble(string tableName, string columnName, bool canNull, string columnType, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                if (string.IsNullOrWhiteSpace(columnType))
                {
                    var table = new SqlServerTable() { Name = tableName };
                    FillColumns(table);
                    columnType = table.Columns.FirstOrDefault(i => i.Name == columnName)?.TypeString;
                }
                if (string.IsNullOrWhiteSpace(columnType)) throw new Exception($"无法确定表{tableName}列{columnName}的类型,无法修改!");
                var objName = db.ParseObjectName(tableName, schemaName);
                var sql = $"alter table {objName.NormalNameQuoted} alter column {db.ParseObjectName(columnName).NameQuoted} {columnType} {(canNull ? "null" : "not null")}";
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 获取指定表、指定列的默认约束名称
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="columnName"></param>
        /// <param name="schemaName"></param>
        /// <returns></returns>
        private string GetColumnDefaultConstraint(string tableName, string columnName, string schemaName = null)
        {
            var objName = db.ParseObjectName(tableName, schemaName);
            // 不指定schema搜索默认约束
            string sql = $@"
select name from sys.objects obj 
where 
obj.object_id=(
	select sysc.default_object_id 
	from sys.columns sysc 
	where 
		sysc.name='{db.ParseObjectName(columnName).Name}' 
		and 
		sysc.object_id=
			(select object_id 
				from sys.objects 
				where name='{tableName}'
			)
)";
            if (schemaName.IsNotNullOrEmptyOrWhiteSpace())
            {
                // 指定schema搜索默认约束
                sql = $@"
select name from sys.objects obj 
where 
obj.object_id=(
	select sysc.default_object_id 
	from sys.columns sysc 
	where 
		sysc.name='{db.ParseObjectName(columnName).Name}' 
		and 
		sysc.object_id=
			(select object_id 
				from sys.objects 
				where name='{tableName}' 
				and schema_id=(select schema_id from sys.schemas where name='{schemaName}')
			)
)";
            }
            return db.SelectScalar<string>(sql);
        }

        /// <summary>
        /// 给指定列修改默认值
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="def">默认值</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public Result AlterColumnDefault(string tableName, string columnName, string def, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                var objName = db.ParseObjectName(tableName, schemaName);
                columnName = db.ParseObjectName(columnName).Name;

                string defname = GetColumnDefaultConstraint(tableName, columnName, schemaName);
                if (defname.IsNullOrEmptyOrWhiteSpace())
                {
                    db.ExecuteSql($"ALTER TABLE {objName.NormalNameQuoted} DROP CONSTRAINT {defname}");
                }
                if (def != null)
                {
                    var sql = $"ALTER TABLE {objName.NormalNameQuoted} ADD CONSTRAINT DF_gene_{objName.Name}_{columnName} DEFAULT ('{def}') FOR {columnName}";
                    db.ExecuteSql(sql);
                }
            });
        }

        /// <summary>
        /// 删除指定表指定列的默认值
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public Result DropColumnDefault(string tableName, string columnName, string schemaName = null)
        {
            return Result.Wrap(() =>
            {
                string defname = GetColumnDefaultConstraint(tableName, columnName, schemaName);
                if (defname.IsNotNullOrEmptyOrWhiteSpace())
                {
                    var objName = db.ParseObjectName(tableName, schemaName);
                    db.ExecuteSql($"ALTER TABLE {objName.NormalNameQuoted} DROP CONSTRAINT {defname}");
                }
            });
        }

        /// <summary>
        /// 给指定表添加一列
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="column">列</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result AddColumn(string tableName, Column column, string schemaName = null)
        {
            var objName = db.ParseObjectName(tableName, schemaName);
            return Result.Wrap(() =>
            {
                string sql = $" alter table {objName.NormalNameQuoted} add [{column.Name}] " + column.TypeString;
                string sqlDesc = "";
                if (!string.IsNullOrWhiteSpace(column.Desc))
                {
                    sqlDesc = $"EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'{db.DealSqlInject(column.Desc)}' , @level0type=N'SCHEMA',@level0name=OBJECT_SCHEMA_NAME(OBJECT_ID('{objName.NormalName}')), @level1type=N'TABLE',@level1name=N'{objName.Name}', @level2type=N'COLUMN',@level2name=N'{column.Name}'";
                }
                if (column.IsNullAble)
                {
                    sql += " null";
                }
                else
                {
                    sql += " not null";
                }
                if (column.IsIdentity)
                {
                    sql += " identity(" + column.IdentityStart + "," + column.IdentityIncre + ")";
                }
                if (column.IsUnique)
                {
                    sql += " unique";
                }
                if (column.HasDefault)
                {
                    sql += " default '" + db.DealSqlInject(column.Default) + "'";
                }
                sql += "\r\n" + sqlDesc;
                db.ExecuteSql(sql);
            });
        }

        /// <summary>
        /// 设置指定列是否是唯一的
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="columnName">列名,可以是多个列,如:"Name,Age",如果指定多个列,那么会先删除单独列的唯一约束</param>
        /// <param name="canUnique">是否是唯一的</param>
        /// <param name="schemaName">指定schema名称</param>
        public Result AlterColumnUnique(string tableName, string columnName, bool canUnique, string schemaName = null)
        {
            var objName = db.ParseObjectName(tableName, schemaName);
            columnName = db.ParseObjectName(columnName).Name;
            return Result.Wrap(() =>
            {
                var constraints = new List<string>();
                var arr = columnName.SplitAndTrimTo<string>(",");
                foreach (var col in arr)
                {
                    string sql = $@"
SELECT idx.name
  FROM sys.indexes idx
  JOIN sys.index_columns idxCol ON (idx.object_id = idxCol.object_id AND
                                   idx.index_id = idxCol.index_id AND
                                   idx.is_unique_constraint = 1)
  JOIN sys.tables tab ON (idx.object_id = tab.object_id)
  JOIN sys.columns col ON (idx.object_id = col.object_id AND
                          idxCol.column_id = col.column_id)
 WHERE 
idx.type=2
and tab.name = '{objName.Name}'
and col.name = '{columnName}'";
                    if (objName.SchemaName.IsNotNullOrEmptyOrWhiteSpace())
                    {
                        sql += $"\r\nand tab.schema_id=SCHEMA_ID('{objName.SchemaName}')";
                    }
                    var constraintName = db.SelectScalar<string>(sql);
                    if (!constraints.Contains(constraintName) && !string.IsNullOrWhiteSpace(constraintName)) constraints.Add(constraintName);
                }
                if (columnName.Contains(','))
                {
                    //组合列 先删除全部的约束
                    if (constraints.Count > 0)
                    {
                        constraints.ForEach(constraintName => db.ExecuteSql($"ALTER TABLE {objName.NormalNameQuoted} DROP CONSTRAINT [{constraintName}]"));
                    }
                    if (canUnique)
                    {
                        var tmp = columnName.Replace(",", "_");
                        db.ExecuteSql($"ALTER TABLE {objName.NormalNameQuoted} ADD CONSTRAINT UQ_gene_{objName.Name}_{tmp} UNIQUE ({columnName})");
                    }
                }
                else
                {
                    //单列
                    if (!canUnique && constraints.Count > 0)
                    {
                        //原来有,指定的没有 则删除唯一约束
                        constraints.ForEach(constraintName => db.ExecuteSql($"ALTER TABLE {objName.NormalNameQuoted} DROP CONSTRAINT [{constraintName}]"));
                    }
                    if (canUnique && constraints.Count == 0)
                    {
                        //原来没有,指定的有 增加唯一约束
                        db.ExecuteSql($"ALTER TABLE {objName.NormalNameQuoted} ADD CONSTRAINT UQ_gene_{objName.Name}_{columnName} UNIQUE ({columnName})");
                    }
                }
            });
        }

        /// <summary>
        /// 创建表,注意创建的内容有:表和列说明/列类型/列自增/列的非空/列的唯一/列的默认值/主键
        /// </summary>
        /// <param name="table">表结构</param>
        public override Result CreateTable(Table table)
        {
            if (table == null) return Result.NotOk("必须指定表属性!");
            //最终create语句
            string sql = $@"create table [{table.Name}] (
";
            //主键列名称,如:name,age
            string priname = "";
            //主键名称,如:name_age
            string prikey = "";
            //表说明以及列说明语句
            string sqldesc = "";
            if (!string.IsNullOrWhiteSpace(table.Desc))
            {
                //给表加说明
                sqldesc += $@"
 EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'{table.Desc}' , @level0type=N'SCHEMA',@level0name=N'{table.SchemaName ?? "dbo"}', @level1type=N'TABLE',@level1name=N'{table.Name}', @level2type=null,@level2name=null";
            }
            table.Columns.ForEach(i =>
            {
                string ideSql = "";
                string nullSql = "";
                string defSql = "";
                string uniSql = "";
                if (i.IsIdentity)
                {
                    ideSql = "identity(" + i.IdentityStart + "," + i.IdentityIncre + ")";
                }
                if (i.IsUnique)
                {
                    uniSql = "unique";
                }
                if (!i.IsNullAble)
                {
                    nullSql = "not null";
                }
                if (!string.IsNullOrWhiteSpace(i.Default))
                {
                    defSql = " default '" + i.Default + "'";
                }
                if (i.IsPrimaryKey)
                {
                    priname += "_" + i.Name;
                    prikey += "," + i.Name;
                }

                sql += string.Format(@" [{0}] {1} {2} {3} {4} {5},
", i.Name, i.TypeString, nullSql, defSql, ideSql, uniSql);
                if (i.Desc != "" && i.Desc != null)
                {
                    sqldesc += $@"
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'{i.Desc}' , @level0type=N'SCHEMA',@level0name=N'{table.SchemaName ?? "dbo"}', @level1type=N'TABLE',@level1name=N'{table.Name}', @level2type=N'COLUMN',@level2name=N'{i.Name}'
";
                }
            });
            priname = priname.Trim('_');
            prikey = prikey.Trim(',');
            if (prikey.Contains(","))
            {
                string[] arr = prikey.Split(',');
                prikey = "";
                for (int i = 0; i < arr.Length; i++)
                {
                    prikey += "[" + arr[i] + "],";
                }
                prikey = prikey.Trim(',');
            }
            string sqlPri = $@"
ALTER TABLE [{table.Name}] ADD CONSTRAINT PK_gene_{table.Name}_{priname} PRIMARY KEY({prikey})";
            if (prikey == "")
            {
                sqlPri = "";
            }
            sql += @"
)
";
            return Result.Wrap(() =>
            {
                db.ExecuteSql(sql);
                db.ExecuteSql(sqlPri);
                db.ExecuteSql(sqldesc);
            });
        }

        /// <summary>
        /// 删除存储过程
        /// </summary>
        /// <param name="procedureName">存储过程名称</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropProcedureIfExist(string procedureName, string schemaName = null)
        {
            var objName = db.ParseObjectName(procedureName, schemaName);
            var sql = $"if (exists (select * from sys.procedures where name = '{objName.Name}')) drop proc {objName.NormalNameQuoted}";
            if (schemaName.IsNotNullOrEmptyOrWhiteSpace())
            {
                sql = $"if (exists (select * from sys.procedures where name = '{objName.Name}' and schema_id=schema_id('{objName.SchemaName}'))) drop proc {objName.NormalNameQuoted}";
            }
            return Result.Wrap(() => db.ExecuteSql(sql));
        }

        /// <summary>
        /// 删除触发器
        /// </summary>
        /// <param name="triggerName">触发器名称</param>
        /// <param name="schemaName">指定schema名称</param>
        /// <returns></returns>
        public override Result DropTriggerIfExist(string triggerName, string schemaName = null)
        {
            var objName = db.ParseObjectName(triggerName, schemaName);
            var sql = $"IF EXISTS(SELECT * FROM sys.triggers WHERE name = N'{objName.Name}') drop trigger {objName.NormalNameQuoted}; ";
            if (schemaName.IsNotNullOrEmptyOrWhiteSpace())
            {
                sql = $"IF EXISTS(SELECT * FROM sys.triggers WHERE name = N'{objName.Name}' and SCHEMA_ID('{objName.SchemaName}')=(select schema_id from sys.objects syso where syso.object_id= parent_id)) drop trigger {db.ParseObjectName(triggerName, schemaName).NormalNameQuoted}; ";
            }
            return Result.Wrap(() => db.ExecuteSql(sql));
        }

        #endregion
    }
}
